package com.gui;

import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.List;
import java.awt.SystemColor;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.Box;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JScrollPane;
import javax.swing.JSeparator;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.JTextPane;
import javax.swing.SwingConstants;
import javax.swing.border.LineBorder;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.filechooser.FileFilter;

import com.tool.ExtensionFileFilter;
import com.tool.ShelfTableModel;
import com.util.Design;
import com.util.Shelf;
import com.util.Workspace;

public class GoRillaMainApp {

	Workspace workspaceObj = null;

	public static final String SPLASH = "startupSplashScreen";
	public static final String LOGIN = "loginPanel";
	public static final String DESIGN = "designPanel";
	public static final String WORKSPACE = "workspacePanel";

	private BufferedImage libImage = null;

	private CardLayout cardLayout = new CardLayout();

	private JMenuBar menuBar;
	private JMenu mnFile, mnEdit, mnHelp;
	private JMenuItem mntmLogin, mntmLogout, mntmExit, mntmPreferences,
			mntmAbout;

	private JFrame frame;
	private JPasswordField passwordField;
	private JPanel panelMainCard, startupSplashScreen, loginPanel,
			loginPanel_01, loginPanel_02, workspacePanel, designPanel,
			panelStatus, workspacePanelCurrentLib, workspacePanelAddNewLib,
			workspacePanelCurrentLib_01, workspacePanelCurrentLib_02,
			panelNewLib_01, panelNewLib_02, panelNewLibGetImage,
			panelNewLibAddLib, shelfPanel;
	private JLabel lblStatusUpdate, lblWelcome, lblUserName, lblPassword,
			lblNewLabel, lblLibraryName, lblFileName, lblImagePreview;
	private JButton btnLogin, btnEditLibrary, btnDeleteLibrary, btnGetImage,
			btnAddLibrary;
	private JSeparator separator;
	private List listOfLibraries;
	private JTextPane txtWorkspaceDirections;
	private JTextField textFieldUserName, textFieldLibraryName, begField,
			endField;
	private ImageIcon ic1;
	private JScrollPane scrollPaneLibImage;
	private JPanel panel;
	private JLabel lblImagePreviewText;
	private JPanel designPanelListOfShelves;
	private JPanel designPanelLibraryPic;
	private JPanel designPanelDirections;
	private JPanel designPanelShelfList;
	private JPanel deisgnPanelButtons;
	private JButton btnAddShelf;
	private JButton btnRemoveShelf;
	private JTextPane txtpnDirectionsForHow;
	private JScrollPane scrollPaneLibDesignImage;
	private ImagePanel designPanelImage;
	private Image designImg = null;
	private JTable shelfTable;

	private ShelfTableModel stm = null;

	private boolean addingShelf = false;

	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					GoRillaMainApp window = new GoRillaMainApp();
					window.frame.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	/**
	 * Create the application.
	 */
	public GoRillaMainApp() {
		initialize();
	}

	/**
	 * Initialize the contents of the frame.
	 */
	private void initialize() {
		frame = new JFrame();
		frame.setBounds(100, 100, 800, 600);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

		// MenuBar
		createMenuBar();

		// MainCardPanel
		createMainCardPanel();

		// SplashScreen card
		createSplashScreenCard();

		// Login card
		createLoginCard();

		// Workspace card
		createWorkspaceCard();

		// Design card
		createDesignCard();

		// Status Panel
		createStatusPanel();
	}

	private void createMainCardPanel() {
		panelMainCard = new JPanel();
		frame.getContentPane().add(panelMainCard, BorderLayout.CENTER);
		panelMainCard.setLayout(new CardLayout(0, 0));
		cardLayout = (CardLayout) panelMainCard.getLayout();
	}

	private void createStatusPanel() {
		panelStatus = new JPanel();
		panelStatus.setBorder(new LineBorder(new Color(0, 0, 0), 1, true));
		frame.getContentPane().add(panelStatus, BorderLayout.SOUTH);

		lblStatusUpdate = new JLabel("...");
		panelStatus.add(lblStatusUpdate);
	}

	private void createWorkspaceCard() {
		workspacePanel = new JPanel();
		panelMainCard.add(workspacePanel, WORKSPACE);
		workspacePanel.setLayout(new BorderLayout(0, 0));

		workspacePanelCurrentLib = new JPanel();
		workspacePanel.add(workspacePanelCurrentLib, BorderLayout.WEST);
		workspacePanelCurrentLib.setLayout(new BorderLayout(0, 0));

		workspacePanelCurrentLib_01 = new JPanel();
		workspacePanelCurrentLib_01.setBackground(SystemColor.control);
		workspacePanelCurrentLib.add(workspacePanelCurrentLib_01,
				BorderLayout.CENTER);
		workspacePanelCurrentLib_01.setLayout(new BorderLayout(0, 0));

		lblNewLabel = new JLabel("List of Current Libraries.");
		lblNewLabel.setFont(new Font("Tahoma", Font.BOLD, 12));
		lblNewLabel.setForeground(Color.BLACK);
		lblNewLabel.setBackground(SystemColor.control);
		workspacePanelCurrentLib_01.add(lblNewLabel, BorderLayout.NORTH);

		listOfLibraries = new List();
		listOfLibraries.setForeground(Color.BLACK);
		listOfLibraries.setFont(new Font("Courier New", Font.PLAIN, 12));
		listOfLibraries.setBackground(SystemColor.control);
		workspacePanelCurrentLib_01.add(listOfLibraries);

		workspacePanelCurrentLib_02 = new JPanel();
		workspacePanelCurrentLib.add(workspacePanelCurrentLib_02,
				BorderLayout.SOUTH);

		workspacePanelCurrentLib_02.setLayout(new GridLayout(2, 1, 0, 0));

		btnEditLibrary = new JButton("Edit Library");
		btnEditLibrary.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				// EDIT SELECTED LIBRARY (OPEN DESIGN CARD)
				String selected = (String) listOfLibraries.getSelectedItem();
				// check for selection
				if (selected == null || selected.equals(" "))
					lblStatusUpdate.setText("No design to edit");
				else {
					workspaceObj.setWorkingDesign(selected);
					updateDesignCard();
					cardLayout.show(panelMainCard, DESIGN);
					onSwitchToDesignCard();
					lblStatusUpdate.setText(selected + " design selected");
				}
			}
		});

		workspacePanelCurrentLib_02.add(btnEditLibrary);

		btnDeleteLibrary = new JButton("Delete Library");
		btnDeleteLibrary.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				// DELETE SELECTED LIBRARY
				String selected = (String) listOfLibraries.getSelectedItem();
				// check for selection
				if (selected == null || selected.equals(" "))
					lblStatusUpdate.setText("No designs");
				else {
					// ask for confirmation
					int toDelete = JOptionPane
							.showConfirmDialog(frame,
									"Are you sure you want to delete "
											+ selected + "?", "Delete Design",
									JOptionPane.YES_NO_OPTION);
					// if yes and successfully deleted from storage
					if (toDelete == JOptionPane.YES_OPTION
							&& workspaceObj.deleteDesign(selected)) {
						updateListOfLibraries();
					} else
						lblStatusUpdate
								.setText("Canceled deleting " + selected);
				}
			}
		});

		workspacePanelCurrentLib_02.add(btnDeleteLibrary);

		txtWorkspaceDirections = new JTextPane();
		txtWorkspaceDirections.setEditable(false);
		txtWorkspaceDirections.setForeground(Color.BLACK);
		txtWorkspaceDirections.setBackground(SystemColor.control);
		txtWorkspaceDirections
				.setText("Please Select a library \r\nfrom the list to edit or \r\ndelete.  \r\n\r\nIf you need to create a \r\nnew library, please use \r\nthe box to the right.\r\n");
		workspacePanelCurrentLib
				.add(txtWorkspaceDirections, BorderLayout.NORTH);

		workspacePanelAddNewLib = new JPanel();
		workspacePanelAddNewLib.setBorder(new LineBorder(new Color(0, 0, 0), 1,
				true));
		workspacePanel.add(workspacePanelAddNewLib, BorderLayout.CENTER);
		workspacePanelAddNewLib.setLayout(new BorderLayout(0, 0));

		panelNewLib_01 = new JPanel();
		workspacePanelAddNewLib.add(panelNewLib_01, BorderLayout.NORTH);
		panelNewLib_01.setLayout(new FlowLayout(FlowLayout.CENTER, 5, 5));

		lblLibraryName = new JLabel("Library Name");
		panelNewLib_01.add(lblLibraryName);

		textFieldLibraryName = new JTextField();
		panelNewLib_01.add(textFieldLibraryName);
		textFieldLibraryName.setColumns(10);

		panelNewLib_02 = new JPanel();
		workspacePanelAddNewLib.add(panelNewLib_02, BorderLayout.CENTER);
		panelNewLib_02.setLayout(new BorderLayout(0, 0));

		panelNewLibGetImage = new JPanel();
		panelNewLib_02.add(panelNewLibGetImage, BorderLayout.NORTH);

		btnGetImage = new JButton("Get Image");
		btnGetImage.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				// Get Image
				JFileChooser chooser = new JFileChooser();
				// File Filter
				FileFilter filter1 = new ExtensionFileFilter("Images",
						new String[] { "JPG", "JPEG", "PNG", "GIF" });
				chooser.addChoosableFileFilter(filter1);
				chooser.setAcceptAllFileFilterUsed(false);

				int returnVal = chooser.showOpenDialog(workspacePanel);
				if (returnVal == JFileChooser.APPROVE_OPTION) {
					// Get file from user, and store it to a buffered img and
					// set preview
					File libraryMap = chooser.getSelectedFile();

					try {
						libImage = ImageIO.read(libraryMap);
						lblFileName.setText(libraryMap.getName());
					} catch (IOException ee) {
						lblStatusUpdate
								.setText("Error creating buffered img of library");
					}

					ic1 = new ImageIcon(libImage);
					lblImagePreview.setText("");
					lblImagePreview.setIcon(ic1);

				} else {
					lblStatusUpdate.setText("Must select a valid image");
				}
			}
		});

		panelNewLibGetImage.add(btnGetImage);

		lblFileName = new JLabel("fileNameExample.jpg");
		panelNewLibGetImage.add(lblFileName);

		scrollPaneLibImage = new JScrollPane();
		panelNewLib_02.add(scrollPaneLibImage, BorderLayout.CENTER);

		lblImagePreview = new JLabel("");
		scrollPaneLibImage.setViewportView(lblImagePreview);

		panel = new JPanel();
		panelNewLib_02.add(panel, BorderLayout.SOUTH);
		panel.setLayout(new BorderLayout(0, 0));

		panelNewLibAddLib = new JPanel();
		FlowLayout flowLayout = (FlowLayout) panelNewLibAddLib.getLayout();
		flowLayout.setAlignment(FlowLayout.RIGHT);
		panel.add(panelNewLibAddLib);

		btnAddLibrary = new JButton("Add Library");
		btnAddLibrary.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {

				if (textFieldLibraryName.getText() != null) {
					String libName = textFieldLibraryName.getText();
					if (libImage != null
							&& !workspaceObj.createDesign(libName, libImage)) {
						lblStatusUpdate.setText("Error uploading to DB");
					} else {
						lblStatusUpdate.setText("Library created");
					}
				} else {
					lblStatusUpdate.setText("Please enter a library name");
				}
				updateListOfLibraries();
			}
		});
		panelNewLibAddLib.add(btnAddLibrary);

		lblImagePreviewText = new JLabel("Image Preview");
		lblImagePreviewText.setHorizontalAlignment(SwingConstants.CENTER);
		panel.add(lblImagePreviewText, BorderLayout.NORTH);

	}

	private void createDesignCard() {
		begField = new JTextField();
		endField = new JTextField();
		begField.setColumns(15);
		endField.setColumns(15);

		shelfPanel = new JPanel();
		shelfPanel.add(new JLabel("Beginning Id:"));
		shelfPanel.add(begField);
		shelfPanel.add(Box.createHorizontalStrut(15)); // a spacer
		shelfPanel.add(new JLabel("Ending Id:"));
		shelfPanel.add(endField);

		designPanel = new JPanel();
		panelMainCard.add(designPanel, DESIGN);
		designPanel.setLayout(new BorderLayout(0, 0));

		designPanelListOfShelves = new JPanel();
		designPanel.add(designPanelListOfShelves, BorderLayout.WEST);
		designPanelListOfShelves.setLayout(new BorderLayout(0, 0));

		designPanelDirections = new JPanel();
		designPanelListOfShelves.add(designPanelDirections, BorderLayout.NORTH);

		txtpnDirectionsForHow = new JTextPane();
		txtpnDirectionsForHow.setBackground(SystemColor.control);
		txtpnDirectionsForHow
				.setText("Add shelves to the library by \r\nclicking the \"Add Shelf\" button\r\nbelow and selecting a poin on\r\nthe map to the right.\r\n\r\nRemove a shelf by selecting a \r\nshelf from the table and selecting\r\n\"Remove Shelf\"");
		designPanelDirections.add(txtpnDirectionsForHow);

		designPanelShelfList = new JPanel();
		designPanelListOfShelves.add(designPanelShelfList, BorderLayout.CENTER);

		deisgnPanelButtons = new JPanel();
		designPanelListOfShelves.add(deisgnPanelButtons, BorderLayout.SOUTH);
		deisgnPanelButtons.setLayout(new GridLayout(3, 1, 0, 0));

		btnAddShelf = new JButton("Add Shelf");
		btnAddShelf.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				// ADD A SHELF LOGIC
				/**
				 * click add shelf select a point enter call number range
				 * confirm save on db
				 */
				addingShelf = true;

			}
		});
		deisgnPanelButtons.add(btnAddShelf);

		btnRemoveShelf = new JButton("Remove Shelf");
		deisgnPanelButtons.add(btnRemoveShelf);

		designPanelLibraryPic = new JPanel();
		designPanel.add(designPanelLibraryPic, BorderLayout.CENTER);
		designPanelLibraryPic.setLayout(new BorderLayout(0, 0));

		scrollPaneLibDesignImage = new JScrollPane();
		designPanelLibraryPic
				.add(scrollPaneLibDesignImage, BorderLayout.CENTER);

		designPanelImage = new ImagePanel(designImg);
		scrollPaneLibDesignImage.setViewportView(designPanelImage);

		designPanelImage.addMouseListener(new MouseAdapter() {
			public void mouseClicked(MouseEvent e) {
				if (addingShelf) {
					int result = JOptionPane.showConfirmDialog(null,
							shelfPanel,
							"Please Enter Beginning and Ending Shelf Ranges",
							JOptionPane.OK_CANCEL_OPTION);
					if (result == JOptionPane.YES_OPTION) {
						Shelf s = new Shelf(e.getX(), e.getY(), begField
								.getText(), endField.getText());
						if (workspaceObj.addShelf(s)) {
							stm.addShelf(s);
							lblStatusUpdate.setText("Added Shelf");
						} else
							lblStatusUpdate.setText("Failed to add shelf");
					}
					addingShelf = false;
				}
			}
		});

	}

	private void createLoginCard() {
		loginPanel = new JPanel();
		panelMainCard.add(loginPanel, LOGIN);
		loginPanel.setLayout(new BorderLayout(0, 0));

		loginPanel_01 = new JPanel();
		loginPanel.add(loginPanel_01, BorderLayout.NORTH);

		lblUserName = new JLabel("User Name:");
		loginPanel_01.add(lblUserName);

		textFieldUserName = new JTextField();
		loginPanel_01.add(textFieldUserName);
		textFieldUserName.setColumns(10);

		lblPassword = new JLabel("Password:");
		loginPanel_01.add(lblPassword);

		passwordField = new JPasswordField();
		passwordField.setColumns(15);
		loginPanel_01.add(passwordField);

		loginPanel_02 = new JPanel();
		loginPanel.add(loginPanel_02, BorderLayout.CENTER);

		btnLogin = new JButton("LOGIN");
		btnLogin.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				// perform login operations.
				if (workspaceObj == null) {
					workspaceObj = new Workspace(textFieldUserName.getText(),
							new String(passwordField.getPassword()));
					if (workspaceObj.isConnected()) {
						lblStatusUpdate.setText("Logged in.");
						// goto Workspace card
						cardLayout.show(panelMainCard, WORKSPACE);
						if (workspaceObj.getDesigns().keySet() != null)
							updateListOfLibraries();
					} else {
						// invalid username/password
						lblStatusUpdate
								.setText("Invalid username/password combination. Please try again.");
						textFieldUserName.setText("");
						passwordField.setText("");
						workspaceObj = null;
					}
				} else {
					// alreeady logged in. what now?!
				}
			}
		});
		loginPanel_02.add(btnLogin);
	}

	private void createMenuBar() {
		menuBar = new JMenuBar();
		frame.setJMenuBar(menuBar);

		mnFile = new JMenu("File");
		menuBar.add(mnFile);

		mntmLogin = new JMenuItem("Login...");
		mntmLogin.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				// GOTO LOGIN CARD!
				cardLayout.show(panelMainCard, LOGIN);
			}
		});
		mnFile.add(mntmLogin);

		mntmLogout = new JMenuItem("Logout...");
		mntmLogout.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				// LOGOUT THE USER
			}
		});
		mnFile.add(mntmLogout);

		mntmExit = new JMenuItem("Exit");
		mntmExit.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				System.exit(0);
			}
		});

		separator = new JSeparator();
		mnFile.add(separator);
		mnFile.add(mntmExit);

		mnEdit = new JMenu("Edit");
		menuBar.add(mnEdit);

		mntmPreferences = new JMenuItem("Preferences");
		mnEdit.add(mntmPreferences);

		mnHelp = new JMenu("Help");
		menuBar.add(mnHelp);

		mntmAbout = new JMenuItem("About...");
		mnHelp.add(mntmAbout);

	}

	private void createSplashScreenCard() {
		startupSplashScreen = new JPanel();
		panelMainCard.add(startupSplashScreen, SPLASH);
		startupSplashScreen.setLayout(new BorderLayout(0, 0));

		lblWelcome = new JLabel(
				"Welcome to GoRILLLA. Please login by selecting File > Login.");
		startupSplashScreen.add(lblWelcome, BorderLayout.NORTH);

	}

	private void updateListOfLibraries() {
		listOfLibraries.removeAll();
		for (String name : workspaceObj.getDesigns().keySet()) {
			listOfLibraries.add(name);
		}
	}

	private void updateDesignCard() {
		Design d = workspaceObj.getWorkingDesign();
		designImg = d.getLibrary().getImg();
		designPanelImage.img = designImg;
		scrollPaneLibDesignImage.setViewportView(designPanelImage);
	}

	private void onSwitchToDesignCard() {
		stm = new ShelfTableModel(workspaceObj.getWorkingDesign().getShelves());
		shelfTable = new JTable(stm);
		stm.addTableModelListener(new TableModelListener() {
			public void tableChanged(TableModelEvent e) {
				int row = e.getFirstRow();
				int col = e.getColumn();

				ShelfTableModel model = (ShelfTableModel) e.getSource();

				Shelf s = model.getRow(row);
				if (workspaceObj.updateShelf(row, s)) {
					lblStatusUpdate.setText("Shelf updated");
				} else {
					lblStatusUpdate.setText("Shelf not updated");
				}
			}
		});

		btnRemoveShelf.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				// REMOVE A SHELF LOGIC
				/**
				 * highlight a shelf click remove shelf confirm removing of
				 * shelf save on db
				 */

				if (workspaceObj.removeShelf(shelfTable.getSelectedRow())) {
					//stm.removeShelf(shelfTable.getSelectedRow());
					stm = new ShelfTableModel(workspaceObj.getWorkingDesign().getShelves());
					shelfTable.setModel(stm);
					lblStatusUpdate.setText("Removed Shelf");

				} else {
					stm = new ShelfTableModel(workspaceObj.getWorkingDesign().getShelves());
					shelfTable.setModel(stm);
					lblStatusUpdate.setText("Failed to remove shelf");

				}
			}
		});

		designPanelShelfList.add(shelfTable, BorderLayout.CENTER);
	}

}
